/**
 * 接口不许定义非public方法
 */
interface C {

    eat()

    drink()

}

/**
 * 接口的另外一种，可以有默认方法的实现
 */
trait D {

    //不实现的方法需要加abstract
    abstract say()

    //方法带上def，否则编译不通过
    def play() {
        println 'i play now'
    }

}


/**
 * 继承自groovy.object
 * groovy默认是public
 *
 */
class B implements C, D {

    String name
    int age

    def sayHi() {
        "hello,my name is $name,age is $age"
    }

    @Override
    def eat() {
        return null
    }

    @Override
    def drink() {
        return null
    }

    @Override
    def say() {
        return null
    }
}

B b = new B(name: 'cherry', age: 30)
println b.sayHi()

class E {

    String name

    //如果重写这个方法，当调用类中的没有的方法时会回调到这个方法
    @Override
    Object invokeMethod(String name, Object args) {
        println "invokeMethod---name:$name,args:$args"
        return null
    }

    //如果重写这个方法，当调用类中的没有的方法时会回调到这个方法，但是此时invokeMethod(）并不会回调
    def methodMissing(String name, def args) {
        println "methodMissing---name:$name,args:$args"
    }
}

E e = new E(name: 'job')
e.cry()

//为类动态添加一个属性
E.metaClass.sex = 'male'

E e1 = new E()
println e1.sex
e1.sex = 'female'
println e1.sex

//为类动态添加一个方法
E.metaClass.cry = {
    println "i cry now! sex is $sex"
}

e1.cry()

//为类动态添加一个静态方法
E.metaClass.static.newInstance = {
    name -> new E(name: name)
}

def e2 = E.newInstance('anne')
println "e2 name is $e2.name ,sex is $e2.sex"

//全局注入meaClass属性和方法，一般单独写在类的一个初始化方法中
//ExpandoMetaClass.enableGlobally()








